
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:valovault_reminder/common/util/val_app_state_tool.dart';
import 'package:flutter/foundation.dart';
import 'package:package_info/package_info.dart';

import '../../http/val_dio_fetch_kit.dart';
import '../config/val_client_url_path.dart';
import 'val_device_info_loader.dart';

/// 埋点
class ValLogKeyEntity{
  
  static const String ValLoggerParamData = "data";
  static const String ValLoggerParamLogType = "log_type";
  static const String ValLoggerParamSubtype = "subtype";
  static const String ValLoggerParamBehavior = "behavior";
  static const String ValLoggerParamDeviceId = "device-id";
  static const String ValLoggerParamAndroidId = "android_id";
  static const String ValLoggerParamUserId = "user_id";
  static const String ValLoggerParamPkg = "pkg";
  static const String ValLoggerParamChnId = "chn_id";
  static const String ValLoggerParamVer = "ver";
  static const String ValLoggerParamPlatform = "platform";
  static const String ValLoggerParamModel = "model";
  static const String ValLoggerParamPVer = "p_ver";
  static const String ValLoggerParamLanId = "lan_id";
  static const String ValLoggerParamSecId = "sec_id";
  static const String ValLoggerParamUtmSource = "utm_source";
  static const String ValLoggerParamAfAdgroupId = "af_adgroup_id";
  static const String ValLoggerParamAfAdset = "af_adset";
  static const String ValLoggerParamAfAdsetId = "af_adset_id";
  static const String ValLoggerParamAfStatus = "af_status";
  static const String ValLoggerParamAfAgency = "af_agency";
  static const String ValLoggerParamAfChannel = "af_channel";
  static const String ValLoggerParamAfCampaign = "campaign";
  static const String ValLoggerParamAfCampaignId = "campaign_id";
  static const String ValLoggerParamCountry = "country";
  static const String ValLoggerParamsysLan = "sys_lan";
}

/// 打点中所有涉及到的页面KEY
class ValConfigLoggerPath {
  static const String launchPage = 'launch';
  static const String quickloginPage = 'quicklogin';
  static const String applelogin = 'applelogin';
  static const String terms = 'terms';
  static const String privacy = 'privacy';
  static const String loginsuccess = 'loginsuccess';

  /// 内购
  static const String purchase = 'purchase';
  static const String createorder = 'createorder';

  /// 用户
  static const String editavatar = 'editavatar';
  static const String logout = 'logout';
  static const String deleteaccount = 'deleteaccount';
  static const String customer = 'customer';

  static const String report = 'report';
  static const String block = 'block';
}

class ValLoggerManager {
  ValLoggerManager._();

  static const String _event = 'event';
  static const String _tm = 'tm';
  static const String _page = 'page';
  static const String _subPage = 'subPage';
  static const String _terPage = 'terPage';
  static const String _broadcasterId = 'broadcasterId';
  static const String _duration = 'duration';

  static void stat({
    String? page,
    String? subPage,
    String? terPage,
    String? broadcasterId,
  }) {
    var map = <String, dynamic>{};
    // ⚠️page传入下方的埋点事件page值
    if (page != null) {
      map[_page] = page;
    }
    if (subPage != null) {
      map[_subPage] = subPage;
    }
    if (terPage != null) {
      map[_terPage] = terPage;
    }
    if (broadcasterId != null) {
      map[_broadcasterId] = broadcasterId;
    }
    map[_duration] = 0;
    map[_event] = 'pv';
    map[_tm] = DateTime.now().millisecondsSinceEpoch;

    if (kDebugMode) {
      log('$map', name: 'LogPvMgr');
    }
    ValLoggerPoint().putLog(ValLoggerType.globalBehavior, map);
  }
}

/// 打点类型
enum ValLoggerType {
  globalBehavior('event', 'global_behavior', 'event'),
clickEvent("event", "click", "event");

final String logType;
final String subType;
final String behavior;

const ValLoggerType(this.logType, this.subType, this.behavior);
}

// 打点管理
class ValLoggerPoint {
  static final ValLoggerPoint _instance = ValLoggerPoint._internal();
  factory ValLoggerPoint() {
    return _instance;
  }
  ValLoggerPoint._internal();

  static const String tag = "LogManger"; // 日志标签
  static const int limitSize = 20; // 打点任务最多缓存长度
  static int _serialId = 0;
  static String launcherId = '';
  final List<Map<String, dynamic>> cacheList = [];
  bool _isWaitingForSend = false; // 是否需要延迟上报

  static setup() async {
    String devideId = await  ValDeviceInfoLoader.getDeviceId() ?? '';
    launcherId = '${DateTime.now().millisecondsSinceEpoch}${devideId}';
  }

  /// 上报日志
  Future<void> putLog(ValLoggerType logType, Map<String, dynamic>? event) async {
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = await _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    cacheList.insert(0, itemData);
    sendDelayed();
  }

  /// 延时发送日志
  void sendDelayed() {
    if (_isWaitingForSend) {
      return;
    }
    _isWaitingForSend = true;
    Timer(const Duration(milliseconds: 2000), () {
      _isWaitingForSend = false;
      sendLog(false);
    });
  }

  /// 发日志打点
  void sendLog(bool forceUploadAll) {
    try {
      List<Map<String, dynamic>> sendList = [];
      if (cacheList.isEmpty) {
        return;
      } else if (cacheList.length >= limitSize && !forceUploadAll) {
        sendList.addAll(cacheList.sublist(0, limitSize));
        cacheList.removeRange(0, limitSize);
      } else {
        sendList.addAll(cacheList);
        cacheList.clear();
      }
      _doUpload(sendList, true);
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
    }
  }

  /// 立马发送日志
  Future<void> putLogRightNow(ValLoggerType logType, Map<String, dynamic>? event) async {
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = await _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    List<Map<String, dynamic>> list = [];
    list.add(itemData);

    _doUpload(list, false);
  }

  /// 执行上传
  Future<void> _doUpload(
      List<Map<String, dynamic>> sendList, bool isContinue) async {
    ValDioFetchKit.getInstance().postJsonWithUrl(
        ValClientUrlPath.postLog,
        sendList,
            (data, errorCode, message) {
          if (errorCode == 0) {
            print('===');
          }else {
          }
        }, (err) {
      print('===');
    });

    // HBRequestUntil.request(HBRequestType.hbEnumPost,hbGlobalLogUrl,newHost: hbLogBaseRequestUrl,requestParam:sendList,isShowLoading: false, (data){
    //   if(isContinue) {
    //     sendDelayed();
    //   }
    // }, (error) {
    // });
  }

  Future<Map<String, dynamic>> _buildItemData(String logType, String subType,
      String behavior, Map<String, dynamic>? event) async {
    String platform = '';
    String model = await ValDeviceInfoLoader.getDeviceModel();
    String deviceId = await ValDeviceInfoLoader.getDeviceId();
    if (Platform.isAndroid) {
      platform = 'Android';
    } else if (Platform.isIOS) {
      platform = 'iOS';
    }
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    String version = packageInfo.version;
    String packageName = packageInfo.packageName;

    Map<String, dynamic> itemData = {};
    itemData[ValLogKeyEntity.ValLoggerParamData] = [event];
    itemData[ValLogKeyEntity.ValLoggerParamLogType] = logType;
    itemData[ValLogKeyEntity.ValLoggerParamSubtype] = subType;
    itemData[ValLogKeyEntity.ValLoggerParamBehavior] = behavior;
    itemData[ValLogKeyEntity.ValLoggerParamDeviceId] = deviceId;
    itemData[ValLogKeyEntity.ValLoggerParamUserId] = ValAppStateTool().accountInfo?.userId ?? '';
    itemData[ValLogKeyEntity.ValLoggerParamPkg] = packageName;
    itemData[ValLogKeyEntity.ValLoggerParamChnId] = '';
    itemData[ValLogKeyEntity.ValLoggerParamVer] = version ;
    itemData[ValLogKeyEntity.ValLoggerParamPlatform] = platform;
    itemData[ValLogKeyEntity.ValLoggerParamModel] = model;
    itemData[ValLogKeyEntity.ValLoggerParamPVer] = packageInfo.buildNumber;
    itemData[ValLogKeyEntity.ValLoggerParamLanId] = launcherId;
    itemData[ValLogKeyEntity.ValLoggerParamSecId] = _serialId++;
    itemData[ValLogKeyEntity.ValLoggerParamsysLan] = ValAppStateTool().currentLocale;
    itemData[ValLogKeyEntity.ValLoggerParamCountry] = ValAppStateTool().accountInfo?.country ?? '';
    return itemData;
  }
}
